package com.infolab.aims.aspect;

import javax.persistence.EntityManager;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceContext;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import com.infolab.aims.common.CommonUtil;
import com.infolab.aims.common.exception.ConcurrentUpdateException;
import com.infolab.aims.common.exception.DataStoreException;
import com.infolab.aims.domain.asset.AssetComponent;
import com.infolab.aims.domain.asset.AssetEquipment;
import com.infolab.aims.domain.purchase.PurchaseOrder;

@Aspect
public class ExceptionAspect  {
 
	private static final Logger logger = Logger.getLogger(ExceptionAspect.class);
	
	@PersistenceContext
	private EntityManager em;
	
	@Around("execution(* com.infolab.aims.web..*(..))")
	public Object afterReturningController(ProceedingJoinPoint pjp) throws Throwable {
		
		Object retval = null;
		try
		{
			retval = pjp.proceed();
		} catch(Exception e)
		{
			logger.error(CommonUtil.getStackTrace(e));
			
			throw e;
		} 
		
		return retval;
		
		
	}
	
	@Around("execution(* com.infolab.aims.service..*(..))")
	public Object afterReturning(ProceedingJoinPoint pjp) throws Throwable {
		
		Object retval = null;
		try
		{
			retval = pjp.proceed();
			em.flush();
		} catch(Exception e)
		{
			if(e instanceof DataStoreException) throw e;
			
			if(e instanceof OptimisticLockException)
			{
				String msg="unknown";
				OptimisticLockException tmp = (OptimisticLockException) e;
				Object obj = tmp.getEntity();
				if(obj instanceof AssetComponent)
				{
					AssetComponent obj1 = (AssetComponent)obj;
					if(obj1.getAssetModel()!=null)
						msg=obj1.getAssetModel().getAssetModelName();
					
				}
				else if(obj instanceof AssetEquipment)
				{
					AssetEquipment obj1 = (AssetEquipment)obj;
					if(obj1.getAssetModel()!=null)
						msg=obj1.getAssetModel().getAssetModelName();
				}
				
				else if(obj instanceof PurchaseOrder)
				{
					PurchaseOrder obj1 = (PurchaseOrder)obj;
					msg=" Purchase Order "+obj1.getPurchaseOrderCode();
				}
				
				throw new ConcurrentUpdateException(e,msg);
				
			}
			
			logger.error(CommonUtil.getStackTrace(e));
			
			Throwable cause = e.getCause();
			if(cause==null) throw new DataStoreException(e);
			
			throw new DataStoreException(cause);
		} 
		
		return retval;
		
		
	}
 
	
}